package hunt.treasure.manager;

import hunt.treasure.GameActivity;
import hunt.treasure.scenes.AbstractScene;
import hunt.treasure.scenes.LoadingScene;
import hunt.treasure.scenes.SplashScene;

import org.andengine.util.debug.Debug;

/**
 * This class is used to manage the scenes.<br>
 * For examples, changing scenes.Applying transition effects to scenes
 * 
 * @author vanhu_000
 * 
 */
public class SceneManager {

	private static final SceneManager INSTANCE = new SceneManager();

	private ResourceManager res = ResourceManager.getInstance();
	private AbstractScene currentScene;
	private LoadingScene loadingScene;

	private SceneManager() {
	}

	/**
	 * Shows splash screen and loads resources on background
	 */
	public void showSplash() {
		Debug.i("Scene: Splash");
		final SplashScene splash = new SplashScene();
		setCurrentScene(splash);
		splash.loadResources();
		splash.create();
		res.engine.setScene(splash);
		res.activity.handler.postDelayed(new Runnable() {

			@Override
			public void run() {
				splash.unloadResources();
				splash.destroy();
			}
		}, GameActivity.SPLASH_DURATION);
	}

	public void showScene(Class<? extends AbstractScene> sceneClazz) {
		if (sceneClazz == LoadingScene.class) {
			throw new IllegalArgumentException(
					"You can't switch to Loading scene");
		}

		try {
			final AbstractScene scene = sceneClazz.newInstance();
			Debug.i("Showing scene " + scene.getClass().getName());

			final AbstractScene oldScene = getCurrentScene();
			if (loadingScene != null) {
				setCurrentScene(loadingScene);
				res.engine.setScene(loadingScene);
			}
			res.activity.handler.post(new Runnable() {

				@Override
				public void run() {
					if (oldScene != null) {
						oldScene.destroy();
						oldScene.unloadResources();
					}
					scene.loadResources();
					scene.create();
					setCurrentScene(scene);
					res.engine.setScene(scene);
				}
			});
		} catch (Exception e) {
			String message = "Error while changing scene";
			Debug.e(message, e);
			throw new RuntimeException(message, e);
		}
	}

	public static SceneManager getInstance() {
		return INSTANCE;
	}

	public AbstractScene getCurrentScene() {
		return currentScene;
	}

	public void setCurrentScene(AbstractScene currentScene) {
		this.currentScene = currentScene;
	}

}
